package com.agileai.portal.bizmoduler.wcm;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.agileai.common.KeyGenerator;
import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.hotweb.bizmoduler.core.TreeAndContentManageImpl;
import com.agileai.hotweb.domain.TreeModel;
import com.agileai.hotweb.domain.core.User;
import com.agileai.util.ListUtil;
import com.agileai.util.MapUtil;
import com.agileai.util.StringUtil;

public class InfomationManageImpl
        extends TreeAndContentManageImpl
        implements InfomationManage {
	private static HashMap<String,List<DataRow>> KeyWordsRelationsCache = new HashMap<String,List<DataRow>>();
	private static HashMap<String,Integer> ReadCountCache = new HashMap<String,Integer>();
	
    public InfomationManageImpl() {
        super();
        this.columnIdField = "COL_ID";
        this.columnParentIdField = "COL_PID";
        this.columnSortField = "COL_ORDERNO";
    }
    
	public void createtContentRecord(String tabId,DataParam param) {
		String statementId = sqlNameSpace+"."+"insert"+StringUtil.upperFirst(tabId)+"Record";
		String curTableName = tabIdAndTableNameMapping.get(tabId);
		processDataType(param, curTableName);
		processPrimaryKeys(curTableName,param);
//		#INFO_ID#,#INFO_SHORTID#,
		String infoId = param.get("INFO_ID");
		String shortInfoId = KeyGenerator.instance().shortKey(infoId);
		param.put("INFO_SHORTID",shortInfoId);
		this.daoHelper.insertRecord(statementId, param);
		String tableMode = tabIdAndTableModeMapping.get(tabId);
		if (TableMode.Many2ManyAndRel.equals(tableMode)){
			statementId = sqlNameSpace+"."+"insert"+StringUtil.upperFirst(tabId)+"Relation";
			this.daoHelper.insertRecord(statementId, param);			
		}
	}    
    
	public List<DataRow> findContentRecords(TreeModel treeModel,String tabId,DataParam param) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+"."+"find"+StringUtil.upperFirst(tabId)+"Records";
		
		DataParam newParam = new DataParam();
		newParam.append(param);
		boolean showChildNodeRecords = "Y".equals(param.get("showChildNodeRecords")); 
		if (showChildNodeRecords){
			newParam.put("showChildNodeRecords","Y");
		}else{
			newParam.put("showChildNodeRecords","N");
		}
		result = this.daoHelper.queryRecords(statementId, newParam);
		if (result != null && showChildNodeRecords){
			Map<String,TreeModel> childrenMap = treeModel.getChildrenMap();
			String columnIdField = this.tabIdAndColFieldMapping.get(tabId);
			List<DataRow> temp = new ArrayList<DataRow>();
			for (int i=0;i < result.size();i++){
				DataRow row = result.get(i);
				row.put("INDEX_ID", i);
				String columnId = row.stringValue(columnIdField);
				if (columnId.equals(treeModel.getId()) || childrenMap.containsKey(columnId)){
					temp.add(row);
				}
			}
			result = temp;
		}
		return result;
	}
	
	@Override
	public void saveInfomationContent(String infomationId, String content,String mobileContent) {
		DataParam updateParam = new DataParam("INFO_ID",infomationId,"INFO_CONTENT",content,"INFO_MOBILE_CONTENT",mobileContent);
		String statementId = sqlNameSpace+"."+"updateWcmInfomationContent";
		this.daoHelper.updateRecord(statementId, updateParam);
		
		DataRow row = this.getContentRecord(infomationId);
		String infoShortId = row.getString("INFO_SHORTID");
		
		ContentRowCache.remove(infomationId);
		ContentRowCache.remove(infoShortId);
	}

    
	@Override
	public void modifyInfomationState(String infomationId, String bizActionType,User user) {
		DataParam updateParam = new DataParam("INFO_ID",infomationId);
		if (InfomationManage.BizActionType.Submit.equals(bizActionType)){
			updateParam.put("INFO_STATE",InfomationManage.InfoState.WaitePublish);
		}
		else if (InfomationManage.BizActionType.UnSubmit.equals(bizActionType)){
			updateParam.put("INFO_STATE",InfomationManage.InfoState.Draft);
		}
		else if (InfomationManage.BizActionType.Approve.equals(bizActionType)){
			updateParam.put("INFO_STATE",InfomationManage.InfoState.Published);
			updateParam.put("INFO_PUBLISHER",user.getUserCode());
			updateParam.put("INFO_PUBLISHER_NAME",user.getUserName());
			updateParam.put("INFO_PUBLISH_TIME",new Date());
		}
		else if (InfomationManage.BizActionType.UnApprove.equals(bizActionType)){
			updateParam.put("INFO_STATE",InfomationManage.InfoState.WaitePublish);
		}
		String statementId = sqlNameSpace+"."+"updateWcmInfomationState";
		this.daoHelper.updateRecord(statementId, updateParam);
		
		DataRow row = this.getContentRecord(infomationId);
		String infoShortId = row.getString("INFO_SHORTID");
		
		ContentRowCache.remove(infoShortId);
		ContentRowCache.remove(infomationId);
	}
	
	@Override
	public void modifyInfomationStates(String infomationId, String bizActionType,User user,Date infoPublishTime,String isChangeTime) {
		DataParam updateParam = new DataParam("INFO_ID",infomationId);
		if (InfomationManage.BizActionType.Submit.equals(bizActionType)){
			updateParam.put("INFO_STATE",InfomationManage.InfoState.WaitePublish);
		}
		else if (InfomationManage.BizActionType.UnSubmit.equals(bizActionType)){
			updateParam.put("INFO_STATE",InfomationManage.InfoState.Draft);
		}
		else if (InfomationManage.BizActionType.Approve.equals(bizActionType)){
			updateParam.put("INFO_STATE",InfomationManage.InfoState.Published);
			updateParam.put("INFO_PUBLISHER",user.getUserCode());
			updateParam.put("INFO_PUBLISHER_NAME",user.getUserName());
			if(infoPublishTime != null && "unchangeTime".equals(isChangeTime)){
				updateParam.put("INFO_PUBLISH_TIME",infoPublishTime);
			}else{
				updateParam.put("INFO_PUBLISH_TIME",new Date());
			}
		}
		else if (InfomationManage.BizActionType.UnApprove.equals(bizActionType)){
			updateParam.put("INFO_STATE",InfomationManage.InfoState.WaitePublish);
		}
		
		String statementId = sqlNameSpace+"."+"updateWcmInfomationState";
		this.daoHelper.updateRecord(statementId, updateParam);
		
		DataRow row = this.getContentRecord(infomationId);
		String infoShortId = row.getString("INFO_SHORTID");
		
		ContentRowCache.remove(infoShortId);
		ContentRowCache.remove(infomationId);
	}
	
	@Override
	public List<DataRow> findContentRecords(String columnId,String sortPolicy,String state) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findWcmInfomationRecordsByColumnId";
		DataParam param = new DataParam("columnId",columnId,"stateCode",state);
		String orderByExpression = this.buildOrderByExpression(sortPolicy);
		param.put("orderByExpression",orderByExpression);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}
	
	private String buildOrderByExpression(String sortPolicy){
		String orderByExpression = "";
		if (SortPolicy.Top8PublishTime.equals(sortPolicy)){
			orderByExpression = "order by a.INFO_SETTOP,a.INFO_PUBLISH_TIME desc";
		}
		else if (SortPolicy.Top8InfomationSort.equals(sortPolicy)){
			orderByExpression = "order by a.INFO_SETTOP,a.INFO_SORT_NO";
		}
		else if (SortPolicy.ReadCountDesc.equals(sortPolicy)){
			orderByExpression = "order by a.INFO_READ_COUNT desc";
		}
		else if (SortPolicy.InfomationSort.equals(sortPolicy)){
			orderByExpression = "order by a.INFO_SORT_NO";			
		}
		else if (SortPolicy.PublishTimeDesc.equals(sortPolicy)){
			orderByExpression = "order by a.INFO_PUBLISH_TIME desc";
		}	
		return orderByExpression;
	}

	@Override
	public List<DataRow> findInfomationKeyWordsRelations(String infomationId) {
		List<DataRow> result = null;
		if (!KeyWordsRelationsCache.containsKey(infomationId)){
			String statementId = sqlNameSpace+".queryInfoKeyWordsRelation";
			DataParam param = new DataParam("INFO_ID",infomationId);
			List<DataRow> temp = this.daoHelper.queryRecords(statementId, param);
			KeyWordsRelationsCache.put(infomationId, temp);
		}
		result = KeyWordsRelationsCache.get(infomationId);
		return result;
	}

	@Override
	public void addInfomationKeyWordsRelation(String infomationId,List<DataRow> relRecords) {
		String statementId = sqlNameSpace+"."+"insertInfoKeyWordsRelation";
		List<DataParam> dataParams = ListUtil.toParamList(relRecords);
		this.daoHelper.batchInsert(statementId, dataParams);
		KeyWordsRelationsCache.remove(infomationId);
	}

	@Override
	public void delInfomationKeyWordsRelation(String infomationId,
			String keyWordsId) {
		DataParam deleteParam = new DataParam("INFO_ID",infomationId,"WORD_ID",keyWordsId);
		String statementId = sqlNameSpace+"."+"deleteInfoKeyWordsRelation";
		this.daoHelper.deleteRecords(statementId, deleteParam);
		
		KeyWordsRelationsCache.remove(infomationId);
	}

	@Override
	public void increaseReadCount(String infomationId) {
		DataParam updateParam = new DataParam("INFO_ID",infomationId);
		String statementId = sqlNameSpace+"."+"increaseReadCount";
		this.daoHelper.updateRecord(statementId, updateParam);
		
		int readCount = findReadCount(infomationId);
		readCount++;
		ReadCountCache.put(infomationId, readCount);
	}

	@Override
	public int findReadCount(String infomationId) {
		int result = 0;
		if (!ReadCountCache.containsKey(infomationId)){
			DataParam queryParam = new DataParam("INFO_ID",infomationId);
			DataRow row = this.getContentRecord("WcmInfomation", queryParam);
			if (row != null){
				String temp = row.stringValue("INFO_READ_COUNT");
				if (!StringUtil.isNullOrEmpty(temp)){
					ReadCountCache.put(infomationId, Integer.parseInt(temp));
				}
			}
		}
		result = ReadCountCache.get(infomationId);
		return result;
	}
	
	@Override
	public int findInfoReviewCount(String infomationId) {
		int result = 0;
		String statementId = sqlNameSpace+".findInfoReviewCount";
		DataParam param = new DataParam("INFO_ID",infomationId);
		DataRow row = this.daoHelper.getRecord(statementId, param);
		result = row.getInt("REVIEW_COUNT");
		return result;
	}
	
	@Override
	public List<DataRow> findRelativeInfomationRecordsByKeyWordsId(
			String keyWordsId, String state, String sortPolicy) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findRelativeInfomationRecords";
		DataParam param = new DataParam("keyWordId",keyWordsId,"stateCode",state);
		String orderByExpression = this.buildOrderByExpression(sortPolicy);
		param.put("orderByExpression",orderByExpression);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> findRelativeInfomationRecordsBysearchWord(
			String searchWord, String state, String sortPolicy) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findRelativeInfomationRecords";
		DataParam param = new DataParam("searchWord",searchWord,"stateCode",state);
		String orderByExpression = this.buildOrderByExpression(sortPolicy);
		param.put("orderByExpression",orderByExpression);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public String getInfomationContent(String infomationId) {
		String result = null;
		DataRow row = this.getContentRecord(infomationId);
		if (row != null && !row.isEmpty()){
			result = row.stringValue("INFO_CONTENT");
		}
		return result;
	}

	@Override
	public List<DataRow> findRefInfoRecords(List<String> infoIdList) {
		List<DataRow> result = new ArrayList<DataRow>();
		if (infoIdList != null && infoIdList.size() > 0){
			String statementId = sqlNameSpace+".findRelInfomationRecords";
			StringBuffer infoIds = new StringBuffer();
			for (int i=0;i < infoIdList.size();i++){
				String tempId = infoIdList.get(i);
				infoIds.append("'").append(tempId).append("'").append(",");
			}
			
			DataParam param = new DataParam("infoIds",infoIds.substring(0,infoIds.length()-1));
			HashMap<String,DataRow> records = this.daoHelper.queryRecords("INFO_ID",statementId, param);
			for (int i=0;i < infoIdList.size();i++){
				String infoId = infoIdList.get(i);
				DataRow row = records.get(infoId);
				if (!MapUtil.isNullOrEmpty(row)){
					result.add(row);
				}
			}
		}
		return result;
	}

	@Override
	public void updateInfoRelInfoIds(String infoId, String relInfoIdsJsonString) {
//		INFO_REL_INFOIDS=#INFO_REL_INFOIDS# where INFO_ID=#INFO_ID#
		DataParam updateParam = new DataParam("INFO_ID",infoId,"INFO_REL_INFOIDS",relInfoIdsJsonString);
		String statementId = sqlNameSpace+"."+"updateRelInfoIds";
		this.daoHelper.updateRecord(statementId, updateParam);
		
		DataRow row = this.getContentRecord(infoId);
		String infoShortId = row.getString("INFO_SHORTID");
		ContentRowCache.remove(infoShortId);
		ContentRowCache.remove(infoId);
	}

	@Override
	public DataRow getContentRecord(String infomationId) {
		DataRow result = null;
		if (!ContentRowCache.containsKey(infomationId)){
			DataParam queryParam = new DataParam("INFO_ID",infomationId);
			DataRow row = this.getContentRecord("WcmInfomation", queryParam);
			if (row != null && !row.isEmpty()){
				ContentRowCache.put(infomationId, row);
			}
		}
		result = ContentRowCache.get(infomationId);
		return result;
	}
	
	public List<DataRow> getContentRecords(String infoIds) {
		List<DataRow> results = new ArrayList<DataRow>();
		DataRow dataRow = null;
		 if(!"".equals(infoIds)){
			 String[] idArray = infoIds.split(",");
			 for(int i=0;i < idArray.length;i++ ){
				 String infomationId = idArray[i];
				 if (!ContentRowCache.containsKey(infomationId)){
						DataParam queryParam = new DataParam("INFO_ID",infomationId);
						DataRow row = this.getContentRecord("WcmInfomation", queryParam);
						if (row != null && !row.isEmpty()){
							ContentRowCache.put(infomationId, row);
						}
					}
				 dataRow = ContentRowCache.get(infomationId);
				 results.add(dataRow);
			 }
		 }
		return results;
	}
	
	@Override
	public DataRow getContentRecord(String tabId, DataParam param) {
		String infomationId = param.get("INFO_ID");
		DataParam queryParam = new DataParam();
		if (infomationId.length() == 36){
			queryParam.put("INFO_ID",infomationId);
		}else{
			queryParam.put("INFO_SHORTID",infomationId);
		}
		return super.getContentRecord(tabId, queryParam);
	}

	public void updatetContentRecord(String tabId,DataParam param) {
		super.updatetContentRecord(tabId,param);
		String infomationId = param.get("INFO_ID");
		DataRow row = this.getContentRecord(infomationId);
		String infoShortId = row.getString("INFO_SHORTID");
		ContentRowCache.remove(infomationId);
		ContentRowCache.remove(infoShortId);
	}
	public void deletContentRecord(String tabId,DataParam param) {
		String infomationId = param.get("INFO_ID");
		DataRow row = this.getContentRecord(infomationId);
		String infoShortId = row.getString("INFO_SHORTID");
		ContentRowCache.remove(infomationId);
		ContentRowCache.remove(infoShortId);
		
		super.deletContentRecord(tabId, param);
	}

	@Override
	public DataRow getCurrentInfoRecord(String infomationId) {
		String statementId = "WcmColumn8Associates.getWcmInfomationRecord";
		DataParam param = new DataParam();
		param.put("INFO_ID", infomationId);
		DataRow result = this.daoHelper.getRecord(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> getLastestNewsRecords(String codeSeg){
		String statementId = "WcmColumn.getLastestNewsRecord";
		DataParam param = new DataParam("codeSeg",codeSeg);
		List<DataRow> result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public int findPraiseCount(DataParam param) {
		int result = 0;
		String infomationId =  param.get("infomationId");
		if (!PraiseCountCache.containsKey(infomationId)){
			String statementId = "WcmColumn.getPraiseCountRecord";
			DataRow row = this.daoHelper.getRecord(statementId, param);
			result = row.getInt("TOTAL_COUNT");
			PraiseCountCache.put(infomationId, result);
		}else{
			result = PraiseCountCache.get(infomationId);
		}
		return result;
	}

	@Override
	public List<DataRow> findPraiseRecords(String infomationId,String userCode) {
		String statementId = "WcmColumn.findPraiseRecords";
		DataParam param = new DataParam("infomationId",infomationId,"userCode",userCode);
		List<DataRow> result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public void insertPraise(DataParam param) {
		String infomationId = param.get("infomationId");
		int praiseCount = findPraiseCount(param);
		PraiseCountCache.put(infomationId, ++praiseCount);
		
		String statementId = "WcmColumn.insertPraiseRecord";
		param.put("WIL_ID", KeyGenerator.instance().genKey());
		this.daoHelper.insertRecord(statementId, param);
	}

	@Override
	public List<DataRow> findContentRecords8Title(String columnId,String sortPolicy, String published) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findWcmInfomationRecordsByColumnIdOld";
		DataParam param = new DataParam("columnId",columnId,"stateCode",published);
		String orderByExpression = this.buildOrderByExpression(sortPolicy);
		param.put("orderByExpression",orderByExpression);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> getRightNews(String colCode,int tabPage,int pageSize) {
		String statementId = sqlNameSpace+".getRightNews";
		int oracleStartIndex = tabPage+1;
		int oracleEndIndex = tabPage + pageSize;
		DataParam param = new DataParam("colCode",colCode,"_mysqltabPage_",tabPage,"_mysqlpageSize_",pageSize,
				"_oracleStartIndex_",oracleStartIndex,"_oracleEndIndex_",oracleEndIndex);
		List<DataRow> result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}
	
	@Override
	public List<DataRow> findContentRecords2Fav(String columnId,String sortPolicy, String published,String userCode) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findFavInfomationRecordsByColumnId";
		DataParam param = new DataParam("columnId",columnId,"stateCode",published,"userCode",userCode);
		String orderByExpression = this.buildOrderByExpression(sortPolicy);
		param.put("orderByExpression",orderByExpression);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> getCurrentRoleList(String userId) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".getCurrentRoleCode";
		DataParam param = new DataParam("userId",userId);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> findUserPrivateInfos(String userCode) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findUserPrivateInfos";
		DataParam param = new DataParam("USER_CODE",userCode);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> findSendMessagesByUserCode(String userCode) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findSendMessagesByUserCode";
		DataParam param = new DataParam("USER_CODE",userCode);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public List<DataRow> findReceiveMessagesByUserCode(String userCode) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findReceiveMessagesByUserCode";
		DataParam param = new DataParam("USER_CODE",userCode);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public DataRow getSendLatestMessage(String sendId) {
		String statementId = sqlNameSpace+".getSendLatestMessageRecord";
		DataParam param = new DataParam("GUID", sendId);
		DataRow result = this.daoHelper.getRecord(statementId, param);
		return result;
	}

	@Override
	public DataRow getReceiveLatestMessage(String receiveId) {
		String statementId = sqlNameSpace+".getReceiveLatestMessageRecord";
		DataParam param = new DataParam("GUID", receiveId);
		DataRow result = this.daoHelper.getRecord(statementId, param);
		return result;
	}
	
	@Override
	public void insertMessageSendRel(String userCode, String receiveCode,String msgId) {
		String statementId = sqlNameSpace+"."+"insertMessageSendRel";
		String guid = KeyGenerator.instance().genKey();
		
		DataParam param = new DataParam("GUID",guid);
		
		
		this.daoHelper.insertRecord(statementId, param);
		
	}

	@Override
	public void insertMessageReceiveRel(String userCode, String receiveCode,String msgId) {
		String statementId = sqlNameSpace+"."+"insertMessageReceiveRel";
		
		DataParam param = new DataParam();
		
		this.daoHelper.insertRecord(statementId, param);
		
	}

	@Override
	public void insertMessageInfo(String msgId, String title, String content) {
		String statementId = sqlNameSpace+"."+"insertMessageInfo";
		
		DataParam param = new DataParam();
		
		this.daoHelper.insertRecord(statementId, param);
		
	}

	@Override
	public List<DataRow> findNewsBySearchWord(String category, String searchWord) {
		List<DataRow> result = null;
		String statementId = sqlNameSpace+".findNewsBySearchWord";
		DataParam param = new DataParam("category",category,"searchWord",searchWord);
		result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public void cancelPraiseRecord(String infomationId, String userCode) {
		String statementId = sqlNameSpace+".deletePraiseRelRecord";
		DataParam param = new DataParam("INFO_ID",infomationId,"USER_CODE",userCode);
		this.daoHelper.deleteRecords(statementId, param);
	}

	@Override
	public List<DataRow> findInfoReviweList(String infoId) {
		String statementId = sqlNameSpace+".findInfoReviweList";
		DataParam param = new DataParam("infoId",infoId);
		List<DataRow> result = this.daoHelper.queryRecords(statementId, param);
		return result;
	}

	@Override
	public HashMap<String, Integer> findInfoListCount() {
		HashMap<String, Integer> result = new HashMap<String, Integer>();
		String statementId = sqlNameSpace+".findInfoListCount";
		DataParam param = new DataParam();
		List<DataRow> countList = this.daoHelper.queryRecords(statementId, param);
		for (int i = 0; i < countList.size(); i++) {
			DataRow row = countList.get(i);
			result.put(row.getString("colCode"), row.getInt("countNums"));
		}
		return result;
	}

	@Override
	public void addNewReview(DataParam insertParam) {
		String statementId = sqlNameSpace+"."+"insertInfoReviewRecord";
		this.daoHelper.insertRecord(statementId, insertParam);
	}
}